//
//  MetalKit.swift
//  ImageFilter
//
//  Created by Amos on 2025/10/10.
//

import Metal
import MetalKit

class MetalContext {
    static let shared = MetalContext()
    
    let device: MTLDevice!
    let commandQueue: MTLCommandQueue!
    let library: MTLLibrary!
    
    var pipelineState: MTLRenderPipelineState!
    var vertexBuffer: MTLBuffer!
    
    private init() {
        device = MTLCreateSystemDefaultDevice()
        commandQueue = device.makeCommandQueue()
        library = device.makeDefaultLibrary()
        
        let vertexFunction = library?.makeFunction(name: "vertexShader")
        let fragmentFunction = library?.makeFunction(name: "fragmentShader")
        
        // 配置渲染管线
        let pipelineDescriptor = MTLRenderPipelineDescriptor()
        pipelineDescriptor.vertexFunction = vertexFunction
        pipelineDescriptor.fragmentFunction = fragmentFunction
        pipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
        
        // 创建顶点描述符，定义顶点数据布局
        let vertexDescriptor = MTLVertexDescriptor()

        // 配置第一个属性（position：float4）
        vertexDescriptor.attributes[0].format = .float4    // 数据格式
        vertexDescriptor.attributes[0].offset = 0           // 在顶点结构体中的偏移量
        vertexDescriptor.attributes[0].bufferIndex = 0      // 关联的缓冲区索引

        // 配置第二个属性（texCoord：float2）
        vertexDescriptor.attributes[1].format = .float2
        vertexDescriptor.attributes[1].offset = MemoryLayout<Float>.stride * 4  // 紧跟在position之后
        vertexDescriptor.attributes[1].bufferIndex = 0

        // 配置缓冲区布局（单个顶点的总大小）
        vertexDescriptor.layouts[0].stride = MemoryLayout<Float>.stride * 6
        vertexDescriptor.layouts[0].stepFunction = .perVertex  // 每个顶点对应一个数据
        vertexDescriptor.layouts[0].stepRate = 1
        
        // 关键：设置顶点描述符（解决stage_in错误的核心）
        pipelineDescriptor.vertexDescriptor = vertexDescriptor
        
        // 创建管线状态
        pipelineState = try! device.makeRenderPipelineState(descriptor: pipelineDescriptor)
        
        // 设置顶点数据（全屏矩形）
        let vertices: [Float] = [
            // 位置(x,y,z,w)      // 纹理坐标(u,v)
            -1.0, -1.0, 0.0, 1.0,  0.0, 1.0,
             1.0, -1.0, 0.0, 1.0,  1.0, 1.0,
            -1.0,  1.0, 0.0, 1.0,  0.0, 0.0,
             1.0,  1.0, 0.0, 1.0,  1.0, 0.0
        ]
        vertexBuffer = device.makeBuffer(bytes: vertices, length: vertices.count * MemoryLayout<Float>.stride, options: [])
    }
}
